package com.us.usws.service.ro.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.iwsh.core.utils.converter.BeanConverter;

import org.apache.commons.lang3.StringUtils;

import com.us.usws.biz.ResourceURIReplacer;
import com.us.usws.common.SiteConstants;
import com.us.usws.common.resourcetree.model.ChannelTree;
import com.us.usws.common.resourcetree.model.VideoCatTree;
import com.us.usws.dao.ChannelDAO;
import com.us.usws.model.domain.base.BaseDict;
import com.us.usws.model.domain.base.BaseVideoCat;
import com.us.usws.model.domain.channel.Channel;
import com.us.usws.model.domain.system.User;
import com.us.usws.model.domain.video.Video;
import com.us.usws.model.flat.channel.DOChannel;
import com.us.usws.service.ro.BaseVideoCatROService;
import com.us.usws.service.ro.ChannelROService;
import com.us.usws.service.ro.VideoROService;
import com.us.usws.support.ext.CacheManager;
import com.us.usws.support.uitls.ServiceFactory;

public class ChannelROServiceImpl implements ChannelROService {

	//private static Log log = LogFactory.getFactory().getInstance(ChannelROServiceImpl.class);

	private VideoROService vService = ServiceFactory.getInstance().getService(VideoROService.class);

	private BaseVideoCatROService videoCatRoService = ServiceFactory.getInstance().getService(BaseVideoCatROService.class);

	private ChannelDAO cDao = new ChannelDAO();

	private BeanConverter bc = BeanConverter.getDefaultConverter();

	/**
	 * get video count
	 */
	@Override
	public int getTotalCount() {
		return cDao.getTotalCount();
	}

	/**
	 * Get all list by pagination.
	 */
	public List<Channel> getChannels(int start, int end) {
		return cDao.getChannels(start, end);
	}

	/**
	 * get all channels
	 */
	public List<Channel> getAllChannels() {
		return cDao.getAllChannels();
	}

	/**
	 * get channel tree
	 */
	public ChannelTree getChannelTree() {
		List<ChannelTree> topChannelTrees = new ArrayList<ChannelTree>();
		ChannelTree root = new ChannelTree();
		root.setName(".");
		root.setChildren(topChannelTrees);
		List<Channel> allChannels = getAllChannels();
		for (Channel channel : allChannels) {
			if ("/".equals(channel.getParentUid())) {
				ChannelTree topChannelTree = bc.gen(channel, ChannelTree.class);
				topChannelTree.setChannelPictureURL(ResourceURIReplacer.getChannelPictureURL(topChannelTree.getUid(),
						topChannelTree.getPicture()));
				topChannelTrees.add(topChannelTree);
				List<ChannelTree> subChannelTrees = new ArrayList<ChannelTree>();
				for (Channel subChannel : allChannels) {
					if (subChannel.getParentUid().equals(channel.getUid())) {
						ChannelTree subChannelTree = bc.gen(subChannel, ChannelTree.class);

						subChannelTree.setLeaf(true);
						subChannelTree.setChannelPictureURL(ResourceURIReplacer.getChannelPictureURL(subChannelTree.getUid(),
								subChannelTree.getPicture()));
						subChannelTrees.add(subChannelTree);
					}
				}
				topChannelTree.setChildren(subChannelTrees);
			}
		}
		return root;
	}

	/**
	 * get channel relateCat tree
	 */
	public VideoCatTree getChannelRelateCatTree(String rateCat) {
		List<VideoCatTree> topChannelRelateCatTrees = new ArrayList<VideoCatTree>();
		VideoCatTree root = new VideoCatTree();
		int id = 0;
		root.setText(".");
		root.setId(id);
		root.setChildren(topChannelRelateCatTrees);
		List<String> rateCats = null;
		String catUid = null;
		if (StringUtils.isNotBlank(rateCat)) {
			rateCats = Arrays.asList(StringUtils.split(rateCat, ","));
		}
		List<BaseDict> dicts = CacheManager.getDictCache().getDicts(SiteConstants.DICT_DOMAIN_VIDEO_TYPE);
		for (BaseDict dict : dicts) {
			VideoCatTree topChannelRelateCatTree = new VideoCatTree();
			topChannelRelateCatTree.setText(dict.getName());
			topChannelRelateCatTree.setId(++id);
			catUid = "type:" + dict.getSepId();
			topChannelRelateCatTree.setCatUid(catUid);

			/*
			 * check has selected cat
			 */
			if (rateCats != null && rateCats.contains(catUid)) {
				topChannelRelateCatTree.setChecked(true);
			}
			topChannelRelateCatTrees.add(topChannelRelateCatTree);
			List<BaseVideoCat> bvcs = videoCatRoService.getRalateCatsByVideoType(dict.getSepId());
			List<VideoCatTree> subCats = new ArrayList<VideoCatTree>();
			for (BaseVideoCat bvc : bvcs) {
				VideoCatTree subChannelRelateCatTree = new VideoCatTree();
				subChannelRelateCatTree.setId(++id);
				catUid = "cat:" + bvc.getUid();
				subChannelRelateCatTree.setCatUid(catUid);
				/*
				 * check has selected cat
				 */
				if (rateCats != null && rateCats.contains(catUid)) {
					subChannelRelateCatTree.setChecked(true);
				}
				subChannelRelateCatTree.setText(bvc.getName());
				subChannelRelateCatTree.setLeaf(true);
				subCats.add(subChannelRelateCatTree);
			}
			topChannelRelateCatTree.setChildren(subCats);
		}
		return root;
	}

	/**
	 * get homepage channels
	 */
	@Override
	public List<Channel> getHomepageChannels() {
		List<Channel> ret = cDao.getChannelsByParentWithTargetLogic(SiteConstants.CHANNEL_ROOT_UID,
				SiteConstants.CHANNEL_TARGET_ROLE_PUBLIC);

		for (Channel each : ret) {
			loadChannelSubProps(each);
			//log.info("After load channels, each=\n" + ObjectUtils.toXML(each));
		}

		return ret;
	}

	/**
	 * get channels for login users
	 */
	@Override
	public List<Channel> getLoginChannels(String userUid, String focusChannelUid) {
		User u = CacheManager.getUserCache().getUser(userUid);
		int role;
		if (u == null) {
			role = SiteConstants.CHANNEL_TARGET_ROLE_PUBLIC;
		} else {
			role = u.getRole() == null ? SiteConstants.CHANNEL_TARGET_ROLE_PUBLIC : u.getRole().intValue();
		}
		List<Channel> ret = cDao.getChannelsByParentWithTargetLogic(SiteConstants.CHANNEL_ROOT_UID, role);
		for (Channel each : ret) {
			loadChannelSubProps(each);
		}
		return ret;
	}

	@Override
	public List<Channel> getNonLoginChannels(String focusChannelUid) {
		List<Channel> ret = cDao.getTopChannelsByTargetRole(SiteConstants.CHANNEL_TARGET_ROLE_PUBLIC);
		for (Channel each : ret) {
			loadChannelSubProps(each);
		}
		return ret;
	}

	/**
	 * get subchannels by parent channel ID
	 */
	@Override
	public List<Channel> getSubChannels(String parentUid) {
		List<Channel> ret = cDao.getChannelsByParentWithTargetLogic(parentUid, SiteConstants.CHANNEL_TARGET_ROLE_ALL);
		for (Channel each : ret) {
			loadChannelSubProps(each);
		}
		return ret;
	}

	/*----------------- private methods ------------------------*/

	/**
	 * load all sub properties, inc. videos and video's cat/file/stat/etc
	 * @param channel
	 */
	private void loadChannelSubProps(Channel c) {
		List<Video> videos = vService.getChannelAllVideos(c.getUid());
		c.setVideos(videos);
	}

	@Override
	public List<Channel> getTopChannelsByTargetRole(int targetRole) {
		return cDao.getTopChannelsByTargetRole(targetRole);
	}

	@Override
	public List<DOChannel> getTopChannels() {
		return cDao.getTopChannels();
	}

	@Override
	public List<DOChannel> getTopChannelsByType(int typeDsid) {
		return cDao.getTopChannelsByType(typeDsid);
	}

}
